package com.janlei.tdd.leetcode.t_692;


import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import static java.util.Objects.requireNonNull;


public class T692 {

    public List<String> topKFrequent(String[] words, int k) {
        List<Node> nodeList = getNodes(words);
        return nodeList.stream()
                .sorted(this::sorter)
                .limit(k)
                .map(Node::getContent)
                .collect(Collectors.toList());
    }


    private int sorter(Node node1, Node node2) {
        if (node1.getTimes() < node2.getTimes()) {
            return 1;
        }

        if (node1.getTimes() > node2.getTimes()) {
            return -1;
        }

        requireNonNull(node1.getContent());
        requireNonNull(node2.getContent());
        return 0;
    }

    private List<Node> getNodes(String[] words) {
        final Map<String, Integer> map = new HashMap<>(16);
        Consumer<String> consumer = word ->
                map.compute(word, (key, value) -> value != null ? value + 1 : 1);

        Arrays.stream(words).forEach(consumer);

        List<Node> nodeList = Lists.newArrayList();
        map.forEach((key, value) -> nodeList.add(new Node(key, value)));
        return nodeList;
    }
}

@Getter
@EqualsAndHashCode
@AllArgsConstructor
class Node {
    private String content;
    private int times;
}